import { Matrix } from "../geom/Matrix";
import { Point } from "../geom/Point";
import { Transform } from "../geom/Transform";

export enum DisplayType {
    Image = 0,
    Armature = 1,
    Mesh = 2,
    BoundingBox = 3,
    Path = 4
}

export abstract class Display {
    type: DisplayType | string = DisplayType[DisplayType.Image].toLowerCase();
    name: string = "";
    transform: Transform = new Transform();
}

export class ImageDisplay extends Display {
    path: string = "";
    pivot: Point = new Point(0.5, 0.5);

    constructor(isDefault: boolean = false) {
        super();

        if (!isDefault) {
            this.type = DisplayType[DisplayType.Image].toLowerCase();
        }
    }
}


export class MeshDisplay extends Display {
    offset: number = -1; // Binary.
    width: number = 0;
    height: number = 0;
    path: string = "";

    vertices: number[] = [];
    uvs: number[] = [];
    triangles: number[] = [];
    weights: number[] = [];
    slotPose: number[] = [];
    bonePose: number[] = [];
    glueWeights: number[] = [];
    glueMeshes: string[] = [];

    edges: number[] = []; // Nonessential.
    userEdges: number[] = []; // Nonessential.

    _userEdges: boolean = true; // TODO
    _boneCount: number = 0;
    _weightCount: number = 0;
    _matrix: Matrix = new Matrix();

    constructor(isDefault: boolean = false) {
        super();

        if (!isDefault) {
            this.type = DisplayType[DisplayType.Mesh].toLowerCase();
        }
    }

    clearToBinary() {
        this.width = 0;
        this.height = 0;
        this.vertices.length = 0;
        this.uvs.length = 0;
        this.triangles.length = 0;
        this.weights.length = 0;
        this.slotPose.length = 0;
        this.bonePose.length = 0;
        this.edges.length = 0;
        this.userEdges.length = 0;
    }

    getBonePoseOffset(boneIndex: number) {
        for (let i = 0, l = this.bonePose.length; i < l; i += 7) {
            if (boneIndex === this.bonePose[i]) {
                return i;
            }
        }

        throw new Error();
    }
}